//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useState } from "react";
import { observer } from 'mobx-react';
import { Button, Card, message, Space } from "antd";
import { ArrowDownOutlined, ArrowLeftOutlined, ArrowRightOutlined, ArrowUpOutlined, CloseOutlined, ColumnHeightOutlined, ColumnWidthOutlined, CopyOutlined, FullscreenExitOutlined, VerticalAlignBottomOutlined, VerticalAlignTopOutlined, VerticalLeftOutlined, VerticalRightOutlined } from "@ant-design/icons";
import { useRoadmapStores } from "../store";
import { request } from "@/utils/request";
import { update_node_position, update_node_size } from "@/api/roadmap_content";
import { writeText } from '@tauri-apps/api/clipboard';

interface PanelProps {
    onChange: () => void;
}

const AlignPanel = observer((props: PanelProps) => {
    const roadmapStore = useRoadmapStores();

    const alignLeft = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let mostLeft: number | null = null;

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (mostLeft == null) {
                mostLeft = curNode.basic_info.node_position.x;
            } else {
                if (curNode.basic_info.node_position.x < mostLeft) {
                    mostLeft = curNode.basic_info.node_position.x;
                }
            }
        }
        if (mostLeft == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.x = mostLeft;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const alignTop = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let mostTop: number | null = null;

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (mostTop == null) {
                mostTop = curNode.basic_info.node_position.y;
            } else {
                if (curNode.basic_info.node_position.y < mostTop) {
                    mostTop = curNode.basic_info.node_position.y;
                }
            }
        }
        if (mostTop == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.y = mostTop;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const alignRight = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let mostRight: number | null = null;

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (mostRight == null) {
                mostRight = curNode.basic_info.node_position.x + curNode.basic_info.node_size.w;
            } else {
                if ((curNode.basic_info.node_position.x + curNode.basic_info.node_size.w) > mostRight) {
                    mostRight = curNode.basic_info.node_position.x + curNode.basic_info.node_size.w;
                }
            }
        }
        if (mostRight == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.x = mostRight - curNode.basic_info.node_size.w;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const alignBottom = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let mostBottom: number | null = null;

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (mostBottom == null) {
                mostBottom = curNode.basic_info.node_position.y + curNode.basic_info.node_size.h;
            } else {
                if ((curNode.basic_info.node_position.y + curNode.basic_info.node_size.h) > mostBottom) {
                    mostBottom = curNode.basic_info.node_position.y + curNode.basic_info.node_size.h;
                }
            }
        }
        if (mostBottom == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.y = mostBottom - curNode.basic_info.node_size.h;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    return (
        <Space>
            <Button type="link" icon={<VerticalRightOutlined style={{ fontSize: "20px" }} />} title="左对齐"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    alignLeft();
                }} />
            <Button type="link" icon={<VerticalAlignTopOutlined style={{ fontSize: "20px" }} />} title="上对齐"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    alignTop();
                }} />
            <Button type="link" icon={<VerticalLeftOutlined style={{ fontSize: "20px" }} />} title="右对齐"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    alignRight();
                }} />
            <Button type="link" icon={<VerticalAlignBottomOutlined style={{ fontSize: "20px" }} />} title="下对齐"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    alignBottom();
                }} />
        </Space>
    );
});

const SizePanel = observer((props: PanelProps) => {
    const roadmapStore = useRoadmapStores();

    const setMaxWidth = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let maxWidth: number | null = null;
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (maxWidth == null) {
                maxWidth = curNode.basic_info.node_size.w;
            } else {
                if (curNode.basic_info.node_size.w > maxWidth) {
                    maxWidth = curNode.basic_info.node_size.w;
                }
            }
        }
        if (maxWidth == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_size.w = maxWidth;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const setMaxHeight = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let maxHeight: number | null = null;
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (maxHeight == null) {
                maxHeight = curNode.basic_info.node_size.h;
            } else {
                if (curNode.basic_info.node_size.h > maxHeight) {
                    maxHeight = curNode.basic_info.node_size.h;
                }
            }
        }
        if (maxHeight == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_size.h = maxHeight;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const setMinSize = () => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        let minWidth: number | null = null;
        let minHeight: number | null = null;

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            if (minWidth == null) {
                minWidth = curNode.basic_info.node_size.w;
            } else {
                if (curNode.basic_info.node_size.w < minWidth) {
                    minWidth = curNode.basic_info.node_size.w;
                }
            }
            if (minHeight == null) {
                minHeight = curNode.basic_info.node_size.h;
            } else {
                if (curNode.basic_info.node_size.h < minHeight) {
                    minHeight = curNode.basic_info.node_size.h;
                }
            }
        }
        if (minWidth == null || minHeight == null) {
            return;
        }
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_size.w = minWidth;
            curNode.basic_info.node_size.h = minHeight;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    return (
        <Space>
            <Button type="link" icon={<ColumnWidthOutlined style={{ fontSize: "20px" }} />} title="最大宽度"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    setMaxWidth();
                }} />

            <Button type="link" icon={<ColumnHeightOutlined style={{ fontSize: "20px" }} />} title="最大高度"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    setMaxHeight();
                }} />
            <Button type="link" icon={<FullscreenExitOutlined style={{ fontSize: "20px" }} />} title="最小尺寸"
                onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    setMinSize();
                }} />
        </Space>);
});

const PositionPanel = observer((props: PanelProps) => {
    const roadmapStore = useRoadmapStores();

    const moveLeft = (value: number) => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.x -= value;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const moveUp = (value: number) => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.y -= value;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const moveRight = (value: number) => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.x += value;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    const moveDown = (value: number) => {
        const tmpNodeList = roadmapStore.nodeList.slice();

        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = tmpNodeList.find(item => item.node_id == nodeId);
            if (curNode == undefined) {
                continue;
            }
            curNode.basic_info.node_position.y += value;
        }
        roadmapStore.nodeList = tmpNodeList;
        props.onChange();
    };

    return (
        <div>
            <div style={{ display: "flex", justifyContent: "center" }}>
                <Space>
                    <ArrowUpOutlined style={{ fontSize: "20px", marginTop: "8px" }} />
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveUp(5);
                        }}>5</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveUp(20);
                        }}>20</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveUp(50);
                        }}>50</Button>
                </Space>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", marginTop: "10px", marginBottom: "10px" }}>
                <Space>
                    <ArrowLeftOutlined style={{ fontSize: "20px", marginTop: "8px" }} />
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveLeft(5);
                        }}>5</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveLeft(20);
                        }}>20</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveLeft(50);
                        }}>50</Button>
                </Space>
                <Space>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveRight(5);
                        }}>5</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveRight(20);
                        }}>20</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveRight(50);
                        }}>50</Button>
                    <ArrowRightOutlined style={{ fontSize: "20px", marginTop: "8px" }} />
                </Space>
            </div>

            <div style={{ display: "flex", justifyContent: "center" }}>
                <Space>
                    <ArrowDownOutlined style={{ fontSize: "20px", marginTop: "8px" }} />
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveDown(5);
                        }}>5</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveDown(20);
                        }}>20</Button>
                    <Button type="link" style={{ fontSize: "20px", minWidth: "0px", padding: "0px 0px" }}
                        onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            moveDown(50);
                        }}>50</Button>
                </Space>
            </div>
        </div>
    );
});


const BatchEditNodePanel = () => {
    const roadmapStore = useRoadmapStores();

    const [hasChange, setHasChange] = useState(false);

    const resetAll = async () => {
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = roadmapStore.getNode(nodeId);
            if (curNode == undefined) {
                continue;
            }
            await roadmapStore.onUpdateNode(nodeId);
        }
        setHasChange(false);
        message.info("重置成功");
    };

    const saveAll = async () => {
        message.info("保存中");
        for (const nodeId of roadmapStore.batchNodeIdList) {
            const curNode = roadmapStore.getNode(nodeId);
            if (curNode == undefined) {
                continue;
            }
            await request(update_node_size({
                session_id: roadmapStore.sessionId,
                roadmap_id: roadmapStore.roadmapId,
                node_id: nodeId,
                node_size: curNode.basic_info.node_size,
            }));
            await request(update_node_position({
                session_id: roadmapStore.sessionId,
                roadmap_id: roadmapStore.roadmapId,
                node_id: nodeId,
                node_position: curNode.basic_info.node_position,
            }));
        }
        setHasChange(false);
        message.info("保存成功");
    };

    const copyNodeList = async () => {
        const tmpNodeList = roadmapStore.nodeList.filter(item => roadmapStore.batchNodeIdList.includes(item.node_id));
        await writeText(JSON.stringify(tmpNodeList, null, 2));
        message.info("已复制到剪切板");
    };

    return (
        <Card title="批量调整" style={{ width: "320px" }} bodyStyle={{ padding: "0px 0px" }} headStyle={{ fontSize: "20px", fontWeight: 600 }}
            extra={
                <Space style={{ height: "40px" }}>
                    <Button type="default" disabled={!hasChange} onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        resetAll();
                    }}>重置</Button>
                    <Button type="primary" disabled={!hasChange} onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        saveAll();
                    }}>保存</Button>
                    <Button type="text" icon={<CloseOutlined />} disabled={hasChange} onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        roadmapStore.clearBatchNodeIdList();
                    }} />
                </Space>
            }>
            <Card title="尺寸" bordered={false} headStyle={{ fontSize: "18px", fontWeight: 700, backgroundColor: "#fbfbfb" }}>
                <SizePanel onChange={() => setHasChange(true)} />
            </Card>
            <Card title="对齐" bordered={false} headStyle={{ fontSize: "18px", fontWeight: 700, backgroundColor: "#fbfbfb" }}>
                <AlignPanel onChange={() => setHasChange(true)} />
            </Card>
            <Card title="位置" bordered={false} headStyle={{ fontSize: "18px", fontWeight: 700, backgroundColor: "#fbfbfb" }}>
                <PositionPanel onChange={() => setHasChange(true)} />
            </Card>
            {roadmapStore.adminUser == true && (
                <Card title="其他" bordered={false} headStyle={{ fontSize: "18px", fontWeight: 700, backgroundColor: "#fbfbfb" }}>
                    <Button type="primary" icon={<CopyOutlined />} onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        copyNodeList();
                    }}>复制节点</Button>
                </Card>
            )}
        </Card>
    );
};

export default observer(BatchEditNodePanel);
